package com.eboss2.sbs.myapplication;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory.Options;
import android.graphics.Color;
import android.os.Build;
import android.os.StrictMode;
import android.support.multidex.MultiDex;
import android.util.Log;
import android.util.TypedValue;
import android.view.WindowManager;
import android.widget.LinearLayout;

import com.alibaba.sdk.android.push.CloudPushService;
import com.alibaba.sdk.android.push.CommonCallback;
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
import com.baidu.mapapi.SDKInitializer;
import com.eboss2.sbs.R;
import com.eboss2.sbs.consts.SharedConsts;
import com.eboss2.sbs.imageloader.UILImageLoader;
import com.eboss2.sbs.model.LoginEntity;
import com.eboss2.sbs.model.LoginMEntity;
import com.google.gson.Gson;
import com.hxchat.HxEaseuiHelper;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMOptions;
import com.hyphenate.easeui.EaseUI;
import com.loopj.android.http.AsyncHttpClient;
import com.lzy.imagepicker.ImagePicker;
import com.lzy.imagepicker.view.CropImageView;
import com.mytools.tool.utils.ScreenUtils;
import com.mytools.tool.utils.SharedUtil;
import com.mytools.tool.utils.StringUtil;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.decode.BaseImageDecoder;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.nostra13.universalimageloader.utils.StorageUtils;
import com.tool.utils.utils.UtilPreference;

import org.litepal.LitePalApplication;

import java.io.File;
import java.util.Iterator;
import java.util.List;

public class MyApplication extends LitePalApplication {

    public static final String TAG = "MyApplication";

    public static Context applicationContext;
    private static Context context;
    private static MyApplication mInstance = null;
    private static AsyncHttpClient httpclient = new AsyncHttpClient();

    public static SharedUtil shareUtil;
    private LoginEntity loginEntity;
    private LoginMEntity loginMEntity;
    //public UpayTask upayTask;			//收钱吧

//    public LocationClient locationClient = null;

    /**
     * nickname for current user, the nickname instead of ID be shown when user receive notification from APNs
     */
    public static String currentUserNick = "";



    public LoginEntity getLoginEntity() {
        if (loginEntity == null) {
            loginEntity = recoveryUserInfoEntity();
            //if(loginEntity!=null){setLoginEntity(loginEntity);}
        }
        return loginEntity;
    }

    public void setLoginEntity(LoginEntity loginEntity) {
        this.loginEntity = loginEntity;
        setBackupUserInfoEntity(loginEntity);
    }

    private static void setBackupUserInfoEntity(LoginEntity loginEntity) {
        String backpu_currentUser = new Gson().toJson(loginEntity);
        shareUtil.setShareStringPara(SharedConsts.CURRENT_USERINFO_FILE, SharedConsts.CURRENT_USERINFO, backpu_currentUser);
    }

    public LoginEntity recoveryUserInfoEntity() {
        String backpu_currentUser = shareUtil.getShareStringPara(SharedConsts.CURRENT_USERINFO_FILE, SharedConsts.CURRENT_USERINFO, "");
        return StringUtil.isNull(backpu_currentUser) ? null : new Gson().fromJson(backpu_currentUser, LoginEntity.class);
    }

    public void cleanUserInfoEntity() {
        shareUtil.removeSharePara(SharedConsts.CURRENT_USERINFO_FILE, SharedConsts.CURRENT_USERINFO);
    }


    public LoginMEntity setNull(){
        loginMEntity = null;
        return loginMEntity;
    }

    public LoginMEntity getLoginMEntity() {
        if (loginMEntity == null) {
            loginMEntity = recoveryUserInfoMEntity();
            //if(loginEntity!=null){setLoginEntity(loginEntity);}
        }
        return loginMEntity;
    }

    public void setLoginMEntity(String loginMEntity) {
//        this.loginMEntity = loginMEntity;
        cleanUserInfoMEntity();
        setBackupUserInfoEntity(loginMEntity);
    }

    private static void setBackupUserInfoEntity(String loginMEntity) {
//        String backpu_currentUser = new Gson().toJson(loginMEntity);
        shareUtil.setShareStringPara(SharedConsts.CURRENT_M_USERINFO_FILE, SharedConsts.CURRENT_M_USERINFO, loginMEntity);
    }

    public LoginMEntity recoveryUserInfoMEntity() {
        String backpu_currentUser = shareUtil.getShareStringPara(SharedConsts.CURRENT_M_USERINFO_FILE, SharedConsts.CURRENT_M_USERINFO, "");
        return StringUtil.isNull(backpu_currentUser) ? null : new Gson().fromJson(backpu_currentUser, LoginMEntity.class);
    }

    public void cleanUserInfoMEntity() {
        shareUtil.removeSharePara(SharedConsts.CURRENT_M_USERINFO_FILE, SharedConsts.CURRENT_M_USERINFO);
    }




    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

    @Override
    public void onCreate() {
        MultiDex.install(this);
        super.onCreate();
        applicationContext = this;
        context = this;
        mInstance = this;
        shareUtil = new SharedUtil(this);

//        setNotify();
        initCloudChannel(this);
        initImageLoaderConfig();
        initImagePicker();


        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            builder.detectFileUriExposure();
        }

//        initEMChat();

//        SDKInitializer.initialize(this);

//        int pid = android.os.Process.myPid();
//        String processAppName = getAppName(pid);
//        // 如果使用到百度地图或者类似启动remote service的第三方库，这个if判断不能少
//        if (processAppName == null || processAppName.equals("")) {
//            // workaround for baidu location sdk
//            // 百度定位sdk，定位服务运行在一个单独的进程，每次定位服务启动的时候，都会调用application::onCreate
//            // 创建新的进程。
//            // 但环信的sdk只需要在主进程中初始化一次。 这个特殊处理是，如果从pid 找不到对应的processInfo
//            // processName，
//            // 则此application::onCreate 是被service 调用的，直接返回
//            return;
//        }
//        initUmeng();
//        initBaiduLocation();
        //initSqb();
//        DemoHelper.getInstance().init(applicationContext);
//        EaseUI.getInstance().init(this, null);
//        EMClient.getInstance().setDebugMode(true);
//        EaseUI.getInstance().init(this, null);

        HxEaseuiHelper.getInstance().init(this.getApplicationContext());
    }

    private void initEMChat() {
        EMOptions options = new EMOptions();
        // 默认添加好友时，是不需要验证的，改成需要验证
        options.setAcceptInvitationAlways(false);

        int pid = android.os.Process.myPid();
        String processAppName = getAppName(pid);
        // 如果APP启用了远程的service，此application:onCreate会被调用2次
        // 为了防止环信SDK被初始化2次，加此判断会保证SDK被初始化1次
        // 默认的APP会在以包名为默认的process name下运行，如果查到的process name不是APP的process name就立即返回

        if (processAppName == null ||!processAppName.equalsIgnoreCase(applicationContext.getPackageName())) {
            Log.e(TAG, "enter the service process!");

            // 则此application::onCreate 是被service 调用的，直接返回
            return;
        }


        //初始化
        EMClient.getInstance().init(applicationContext, options);
        //在做打包混淆时，关闭debug模式，避免消耗不必要的资源
        EMClient.getInstance().setDebugMode(true);
    }









    /**
     * 初始化云推送通道
     * @param applicationContext
     */
    private void initCloudChannel(Context applicationContext) {
        PushServiceFactory.init(applicationContext);
        final CloudPushService pushService = PushServiceFactory.getCloudPushService();
//        pushService.setLogLevel(CloudPushService.LOG_DEBUG);
        pushService.register(applicationContext, new CommonCallback() {
            @Override
            public void onSuccess(String response) {
                Log.e(TAG, "init cloudchannel success");

                Log.e(TAG, pushService.getDeviceId());
                UtilPreference.saveString(context, "channelId", pushService.getDeviceId());
            }
            @Override
            public void onFailed(String errorCode, String errorMessage) {
                Log.e(TAG, "init cloudchannel failed -- errorcode:" + errorCode + " -- errorMessage:" + errorMessage);
            }
        });


    }


    private void initImageLoaderConfig() {

        File cacheDir = StorageUtils.getOwnCacheDirectory(this, "imageloader/Cache");

        DisplayImageOptions options = new DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.ic_public_nophoto)                            // 设置图片加载时的默认图片
                .showImageForEmptyUri(R.drawable.ic_public_nophoto)                            // 设置图片URI为空时默认图片
                .showImageOnFail(R.drawable.ic_public_nophoto)                                // 设置图片加载失败的默认图片
                .resetViewBeforeLoading(false)                                    // 设置是否将View在加载前复位
                //.delayBeforeLoading(100)										// 设置延迟部分时间才开始加载   默认为0
                .cacheInMemory(true)                                            // 设置添加到内存缓存   默认为false
                .cacheOnDisc(true)                                                // 设置添加到硬盘缓存   默认为false
                //.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)			// 设置规模类型的解码图像   默认为ImageScaleType.IN_SAMPLE_POWER_OF_2
                //.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
                //.bitmapConfig(Bitmap.Config.ARGB_8888)							// 设置位图图像解码配置   默认为Bitmap.Config.ARGB_8888
                .bitmapConfig(Bitmap.Config.RGB_565)                            // 设置图片加载或解码过程中发生错误显示的图片
                .decodingOptions(new Options())                                    // 设置选项的图像解码
                //.displayer(new FadeInBitmapDisplayer(300))						// 设置自定义显示器   默认为DefaultConfigurationFactory.createBitmapDisplayer()  设置图片渐显的时间
                //。displayer(new RoundedBitmapDisplayer(5))       				//图片圆角显示，值为整数
                .build(); // 创建配置过得DisplayImageOption对象

        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
                //.memoryCacheExtraOptions(720, 1280)								// 内存缓存的设置选项 (最大图片宽度,最大图片高度) 默认当前屏幕分辨率
                //.discCacheFileNameGenerator(new Md5FileNameGenerator())			// 设置硬盘缓存文件名生成规范   // 默认为new HashCodeFileNameGenerator()
//                .discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null)    // 硬盘缓存的设置选项 (最大图片宽度,最大图片高度,压缩格式,压缩质量，处理器)
                .denyCacheImageMultipleSizesInMemory()                            // 设置拒绝缓存在内存中一个图片多个大小 默认为允许,(同一个图片URL)根据不同大小的imageview保存不同大小图片
//                .discCache(new UnlimitedDiscCache(cacheDir))                    // 自定义缓存路径
                //.discCache(new UnlimitedDiscCache(StorageUtils.getCacheDirectory(getApplicationContext())))	//设置硬盘缓存   默认为StorageUtils.getCacheDirectory(getApplicationContext())  即/mnt/sdcard/android/data/包名/cache/
                .discCacheSize(10 * 1024 * 1024)                                // 设置硬盘缓存的最大大小
                .discCacheFileCount(100)                                        // 设置硬盘缓存的文件的最多个数
                .threadPoolSize(6)                                                // 设置显示图片线程池大小，默认为3
                .threadPriority(Thread.NORM_PRIORITY - 2)                        // 设置图片加载线程的优先级,默认为Thread.NORM_PRIORITY-1
                .tasksProcessingOrder(QueueProcessingType.FIFO)                    // 设置图片加载和显示队列处理的类型 默认为QueueProcessingType.FIFO
                //.taskExecutor(DefaultConfigurationFactory.createExecutor(6, Thread.NORM_PRIORITY - 2, QueueProcessingType.FIFO))
                .memoryCache(new LruMemoryCache(4 * 1024 * 1024))                // 设置内存缓存 默认为一个当前应用可用内存的1/8大小的LruMemoryCache
                .memoryCacheSize(4 * 1024 * 1024)                                // 设置内存缓存的最大大小 默认为一个当前应用可用内存的1/8
                .memoryCacheSizePercentage(13)                                    // 设置内存缓存最大大小占当前应用可用内存的百分比 默认为一个当前应用可用内存的1/8
                .imageDownloader(new BaseImageDownloader(this, 10 * 1000, 10 * 1000))    // 超时时间 10秒
                //.imageDownloader(new HttpClientImageDownloader(getApplicationContext(), new DefaultHttpClient()))	//设置图片下载器   默认为 DefaultConfigurationFactory.createBitmapDisplayer()
                .imageDecoder(new BaseImageDecoder(true))
                //.imageDecoder(DefaultConfigurationFactory.createImageDecoder(false))	//设置图片解码器   默认为DefaultConfigurationFactory.createImageDecoder(false)
                .defaultDisplayImageOptions(options)
                //.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) 		// 设置默认的图片显示选项   默认为DisplayImageOptions.createSimple()
                .writeDebugLogs()                                                        // 打印DebugLogs
                .build();// 开始构建

        ImageLoader.getInstance().init(config);

        com.nostra13.universalimageloader.utils.L.disableLogging();
        //com.nostra13.universalimageloader.utils.L.enableLogging();

    }

    private void initImagePicker(){
        ImagePicker imagePicker = ImagePicker.getInstance();
        imagePicker.setImageLoader(new UILImageLoader());   //设置图片加载器
        imagePicker.setShowCamera(true);  //显示拍照按钮
        imagePicker.setCrop(false);        //允许裁剪（单选才有效）
        imagePicker.setSaveRectangle(true); //是否按矩形区域保存
        imagePicker.setSelectLimit(5);    //选中数量限制
        imagePicker.setStyle(CropImageView.Style.RECTANGLE);  //裁剪框的形状
        imagePicker.setFocusWidth(800);   //裁剪框的宽度。单位像素（圆形自动取宽高最小值）
        imagePicker.setFocusHeight(800);  //裁剪框的高度。单位像素（圆形自动取宽高最小值）
        imagePicker.setOutPutX(1000);//保存文件的宽度。单位像素
        imagePicker.setOutPutY(1000);//保存文件的高度。单位像素
    }


//    private void initLocation() {
//        LocationClientOption option = new LocationClientOption();
//        option.setLocationMode(LocationMode.Hight_Accuracy);//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
//        option.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系
//        int span = 1000;
//        option.setScanSpan(span);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
//        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
//        option.setOpenGps(true);//可选，默认false,设置是否使用gps
//        option.setLocationNotify(true);//可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
//        option.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
//        option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
//        option.setIgnoreKillProcess(false);//可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
//        option.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
//        option.setEnableSimulateGps(false);//可选，默认false，设置是否需要过滤gps仿真结果，默认需要
//        locationClient.setLocOption(option);
//    }


    public static MyApplication getmInstance() {
        return mInstance;
    }

    public static AsyncHttpClient getHttpclient() {
        return httpclient;
    }

    private String getAppName(int pID) {
        String processName = null;
        ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
        List l = am.getRunningAppProcesses();
        Iterator i = l.iterator();
        PackageManager pm = this.getPackageManager();
        while (i.hasNext()) {
            ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
            try {
                if (info.pid == pID) {
                    processName = info.processName;
                    return processName;
                }
            } catch (Exception e) {
                // Log.d("Process", "Error>> :"+ e.toString());
            }
        }
        return processName;
    }



    public static Context getContext() {
        return context;
    }


}
